<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/blogwebpage/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/blogwebpage/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/blogwebpage/images/favicon.ico">
  <link rel="mask-icon" href="/blogwebpage/images/logo.svg" color="#222">
  <meta name="msvalidate.01" content="9BDlx6FiNE">

<link rel="stylesheet" href="/blogwebpage/css/main.css">


<link rel="stylesheet" href="/blogwebpage/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"wangkejie.gitee.io","root":"/blogwebpage/","scheme":"Gemini","version":"7.8.0","exturl":true,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":true,"style":"default"},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="如何提升 tableview 的流畅度？本质上是降低 CPU、GPU 的工作，从这两个大的方面去提升性能。  CPU：对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制 GPU：纹理的渲染  卡顿优化在 CPU 层面 尽量用轻量级的对象，比如用不到事件处理的地方，可以考虑使用 CALayer 取代 UIView 不要频繁地调用 UIView 的相关属性，">
<meta property="og:type" content="article">
<meta property="og:title" content="iOS性能优化">
<meta property="og:url" content="https://wangkejie.gitee.io/blogwebpage/iOS/performance/index.html">
<meta property="og:site_name" content="王科杰">
<meta property="og:description" content="如何提升 tableview 的流畅度？本质上是降低 CPU、GPU 的工作，从这两个大的方面去提升性能。  CPU：对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制 GPU：纹理的渲染  卡顿优化在 CPU 层面 尽量用轻量级的对象，比如用不到事件处理的地方，可以考虑使用 CALayer 取代 UIView 不要频繁地调用 UIView 的相关属性，">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2015-07-10T04:24:27.000Z">
<meta property="article:modified_time" content="2021-06-26T11:33:05.419Z">
<meta property="article:author" content="Jack Wang">
<meta property="article:tag" content="iOS性能优化">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://wangkejie.gitee.io/blogwebpage/iOS/performance/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>iOS性能优化 | 王科杰</title>
  


  <script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?93e26277de0cf2c5851167f2c6dcaa7d";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/blogwebpage/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">王科杰</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">Jack's Notes</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/blogwebpage/" rel="section"><i class="home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/blogwebpage/archives/" rel="section"><i class="archive fa-fw"></i>归档<span class="badge">52</span></a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/blogwebpage/me/" rel="section"><i class="user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/blogwebpage/tags/" rel="section"><i class="tags fa-fw"></i>标签<span class="badge">54</span></a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/blogwebpage/categories/" rel="section"><i class="th fa-fw"></i>分类<span class="badge">56</span></a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

  <span class="exturl github-corner" data-url="aHR0cHM6Ly9naXRodWIuY29tL0phY2stVmluZw==" title="Follow me on GitHub" aria-label="Follow me on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></span>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://wangkejie.gitee.io/blogwebpage/iOS/performance/index.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/blogwebpage/images/avatar.gif">
      <meta itemprop="name" content="Jack Wang">
      <meta itemprop="description" content="书山有路勤为径，学海无涯苦作舟！">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="王科杰">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          iOS性能优化
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2015-07-10 12:24:27" itemprop="dateCreated datePublished" datetime="2015-07-10T12:24:27+08:00">2015-07-10</time>
            </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blogwebpage/categories/iOS/" itemprop="url" rel="index"><span itemprop="name">iOS</span></a>
                </span>
                  ，
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blogwebpage/categories/iOS/iOS%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" itemprop="url" rel="index"><span itemprop="name">iOS性能优化</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h2 id="如何提升-tableview-的流畅度？"><a href="#如何提升-tableview-的流畅度？" class="headerlink" title="如何提升 tableview 的流畅度？"></a>如何提升 <code>tableview</code> 的流畅度？</h2><p>本质上是降低 CPU、GPU 的工作，从这两个大的方面去提升性能。</p>
<ul>
<li>CPU：对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制</li>
<li>GPU：纹理的渲染</li>
</ul>
<h3 id="卡顿优化在-CPU-层面"><a href="#卡顿优化在-CPU-层面" class="headerlink" title="卡顿优化在 CPU 层面"></a>卡顿优化在 CPU 层面</h3><ul>
<li>尽量用轻量级的对象，比如用不到事件处理的地方，可以考虑使用 CALayer 取代 UIView</li>
<li>不要频繁地调用 UIView 的相关属性，比如 frame、bounds、transform 等属性，尽量减少不必要的修改</li>
<li>尽量提前计算好布局，在有需要时一次性调整对应的属性，不要多次修改属性</li>
<li>Autolayout 会比直接设置 frame 消耗更多的 CPU 资源</li>
<li>图片的 size 最好刚好跟 UIImageView 的 size 保持一致</li>
<li>控制一下线程的最大并发数量</li>
<li>尽量把耗时的操作放到子线程<ul>
<li>文本处理（尺寸计算、绘制）</li>
<li>图片处理（解码、绘制）</li>
</ul>
</li>
</ul>
<h3 id="卡顿优化在-GPU层面"><a href="#卡顿优化在-GPU层面" class="headerlink" title="卡顿优化在 GPU层面"></a>卡顿优化在 GPU层面</h3><ul>
<li>尽量避免短时间内大量图片的显示，尽可能将多张图片合成一张进行显示</li>
<li>GPU能处理的最大纹理尺寸是 4096x4096，一旦超过这个尺寸，就会占用 CPU 资源进行处理，所以纹理尽量不要超过这个尺寸</li>
<li>尽量减少视图数量和层次</li>
<li>减少透明的视图（alpha&lt;1），不透明的就设置 opaque 为 YES</li>
<li>尽量避免出现离屏渲染</li>
</ul>
<p><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmliaXJlbWUuY29tLzIwMTUvMTEvMTIvc21vb3RoX3VzZXJfaW50ZXJmYWNlc19mb3JfaW9zLw==">iOS 保持界面流畅的技巧<i class="fa fa-external-link-alt"></i></span></p>
<h4 id="1-预排版，提前计算"><a href="#1-预排版，提前计算" class="headerlink" title="1.预排版，提前计算"></a>1.预排版，提前计算</h4><p>在接收到服务端返回的数据后，尽量将 <code>CoreText</code> 排版的结果、单个控件的高度、<code>cell</code> 整体的高度提前计算好，将其存储在模型的属性中。需要使用时，直接从模型中往外取，避免了计算的过程。</p>
<p>尽量少用 <code>UILabel</code>，可以使用 <code>CALayer</code> 。避免使用 <code>AutoLayout</code> 的自动布局技术，采取纯代码的方式 </p>
<blockquote>
<p>Autolayout 是苹果本身提倡的技术，在大部分情况下也能很好的提升开发效率，但是 Autolayout 对于复杂视图来说常常会产生严重的性能问题。随着视图数量的增长，Autolayout 带来的 CPU 消耗会呈指数级上升。具体数据可以看这个文章：<span class="exturl" data-url="aHR0cDovL3BpbGt5Lm1lLzM2LyVFMyU4MCU4Mg==">http://pilky.me/36/。<i class="fa fa-external-link-alt"></i></span> 如果你不想手动调整 frame 等属性，你可以用一些工具方法替代（比如常见的 left/right/top/bottom/width/height 快捷属性），或者使用 ComponentKit、<a href="./iOS/thirdpart/asdk.html">AsyncDisplayKit</a> 等框架。</p>
</blockquote>
<h4 id="2-预渲染，提前绘制"><a href="#2-预渲染，提前绘制" class="headerlink" title="2.预渲染，提前绘制"></a>2.预渲染，提前绘制</h4><p>例如圆形的图标可以提前在，在接收到网络返回数据时，在后台线程进行处理，直接存储在模型数据里，回到主线程后直接调用就可以了</p>
<p>避免使用 CALayer 的 Border、corner、shadow、mask 等技术，这些都会触发离屏渲染。</p>
<h4 id="3-异步绘制"><a href="#3-异步绘制" class="headerlink" title="3.异步绘制"></a>3.异步绘制</h4><h4 id="4-全局并发线程"><a href="#4-全局并发线程" class="headerlink" title="4.全局并发线程"></a>4.全局并发线程</h4><h4 id="5-高效的图片异步加载"><a href="#5-高效的图片异步加载" class="headerlink" title="5.高效的图片异步加载"></a>5.高效的图片异步加载</h4><h2 id="如何有效降低-APP-包的大小？"><a href="#如何有效降低-APP-包的大小？" class="headerlink" title="如何有效降低 APP 包的大小？"></a>如何有效降低 <code>APP</code> 包的大小？</h2><p>降低包大小需要从两方面着手</p>
<h3 id="可执行文件"><a href="#可执行文件" class="headerlink" title="可执行文件"></a>可执行文件</h3><ul>
<li><p>编译器优化</p>
<ul>
<li>Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default 设置为 YES</li>
<li>去掉异常支持，Enable C++ Exceptions、Enable Objective-C Exceptions 设置为 NO， Other C Flags 添加 -fno-exceptions   </li>
</ul>
</li>
<li><p>利用 AppCode 检测未使用的代码：菜单栏 -&gt; Code -&gt; Inspect Code</p>
</li>
<li><p>编写LLVM插件检测出重复代码、未被调用的代码</p>
</li>
</ul>
<h3 id="资源"><a href="#资源" class="headerlink" title="资源"></a>资源</h3><blockquote>
<p>资源包括 图片、音频、视频 等</p>
</blockquote>
<ul>
<li>优化的方式可以对资源进行无损的压缩</li>
<li>去除没有用到的资源： <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3RpbnltaW5kL0xTVW51c2VkUmVzb3VyY2Vz">https://github.com/tinymind/LSUnusedResources<i class="fa fa-external-link-alt"></i></span></li>
</ul>
<h2 id="继续优化"><a href="#继续优化" class="headerlink" title="继续优化"></a>继续优化</h2><h3 id="1、重用和延迟加载-lazy-load-Views"><a href="#1、重用和延迟加载-lazy-load-Views" class="headerlink" title="1、重用和延迟加载(lazy load) Views"></a>1、重用和延迟加载(lazy load) Views</h3><ul>
<li>更多的view意味着更多的渲染，也就是更多的CPU和内存消耗，对于那种嵌套了很多view在UIScrollView里边的app更是如此。</li>
<li>这里我们用到的技巧就是模仿UITableView和UICollectionView的操作: 不要一次创建所有的subview，而是当需要时才创建，当它们完成了使命，把他们放进一个可重用的队列中。这样的话你就只需要在滚动发生时创建你的views，避免了不划算的内存分配。</li>
</ul>
<h3 id="2、Cache-Cache-还是Cache"><a href="#2、Cache-Cache-还是Cache" class="headerlink" title="2、Cache, Cache, 还是Cache!"></a>2、Cache, Cache, 还是Cache!</h3><ul>
<li>一个极好的原则就是，缓存所需要的，也就是那些不大可能改变但是需要经常读取的东西。</li>
<li>我们能缓存些什么呢？一些选项是，远端服务器的响应，图片，甚至计算结果，比如UITableView的行高。</li>
<li>NSCache和NSDictionary类似，不同的是系统回收内存的时候它会自动删掉它的内容。</li>
</ul>
<h3 id="3、权衡渲染方法-性能能还是要bundle保持合适的大小。"><a href="#3、权衡渲染方法-性能能还是要bundle保持合适的大小。" class="headerlink" title="3、权衡渲染方法.性能能还是要bundle保持合适的大小。"></a>3、权衡渲染方法.性能能还是要bundle保持合适的大小。</h3><h3 id="4、处理内存警告-移除对缓存，图片object和其他一些可以重创建的objects的strong-references"><a href="#4、处理内存警告-移除对缓存，图片object和其他一些可以重创建的objects的strong-references" class="headerlink" title="4、处理内存警告.移除对缓存，图片object和其他一些可以重创建的objects的strong references."></a>4、处理内存警告.移除对缓存，图片object和其他一些可以重创建的objects的strong references.</h3><h3 id="5、重用大开销对象"><a href="#5、重用大开销对象" class="headerlink" title="5、重用大开销对象"></a>5、重用大开销对象</h3><h3 id="6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。"><a href="#6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。" class="headerlink" title="6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。"></a>6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。</h3><h3 id="7、避免反复处理数据-在服务器端和客户端使用相同的数据结构很重要。"><a href="#7、避免反复处理数据-在服务器端和客户端使用相同的数据结构很重要。" class="headerlink" title="7、避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。"></a>7、避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。</h3><h3 id="8、选择正确的数据格式-解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON-deserialization-就更加方便使用了。但是XML也有XML的好处，比如使用SAX-来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。"><a href="#8、选择正确的数据格式-解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON-deserialization-就更加方便使用了。但是XML也有XML的好处，比如使用SAX-来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。" class="headerlink" title="8、选择正确的数据格式.解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON deserialization 就更加方便使用了。但是XML也有XML的好处，比如使用SAX 来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。"></a>8、选择正确的数据格式.解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON deserialization 就更加方便使用了。但是XML也有XML的好处，比如使用SAX 来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。</h3><h3 id="9、正确设定背景图片"><a href="#9、正确设定背景图片" class="headerlink" title="9、正确设定背景图片"></a>9、正确设定背景图片</h3><ul>
<li>全屏背景图，在view中添加一个UIImageView作为一个子View</li>
<li>只是某个小的view的背景图，你就需要用UIColor的colorWithPatternImage来做了，它会更快地渲染也不会花费很多内存：</li>
</ul>
<h3 id="10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。"><a href="#10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。" class="headerlink" title="10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。"></a>10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。</h3><h3 id="11、Shadow-Path-。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow-path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update-shadow-path"><a href="#11、Shadow-Path-。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow-path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update-shadow-path" class="headerlink" title="11、Shadow Path 。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update shadow path."></a>11、Shadow Path 。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update shadow path.</h3><h3 id="12、优化Table-View"><a href="#12、优化Table-View" class="headerlink" title="12、优化Table View"></a>12、优化Table View</h3><ul>
<li>正确使用reuseIdentifier来重用cells</li>
<li>尽量使所有的view opaque，包括cell自身</li>
<li>避免渐变，图片缩放，后台选人</li>
<li>缓存行高</li>
<li>如果cell内现实的内容来自web，使用异步加载，缓存请求结果</li>
<li>使用shadowPath来画阴影</li>
<li>减少subviews的数量</li>
<li>尽量不适用cellForRowAtIndexPath:，如果你需要用到它，只用-一次然后缓存结果</li>
<li>使用正确的数据结构来存储数据</li>
<li>使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight来设定固定的高，不要请求delegate</li>
</ul>
<h3 id="13、选择正确的数据存储选项"><a href="#13、选择正确的数据存储选项" class="headerlink" title="13、选择正确的数据存储选项"></a>13、选择正确的数据存储选项</h3><ul>
<li>NSUserDefaults的问题是什么？虽然它很nice也很便捷，但是它只适用于小数据，比如一些简单的布尔型的设置选项，再大点你就要考虑其它方式了</li>
<li>XML这种结构化档案呢？总体来说，你需要读取整个文件到内存里去解析，这样是很不经济的。使用SAX又是一个很麻烦的事情。</li>
<li>NSCoding？不幸的是，它也需要读写文件，所以也有以上问题。</li>
<li>在这种应用场景下，使用SQLite 或者 Core Data比较好。使用这些技术你用特定的查询语句就能只加载你需要的对象。</li>
<li>在性能层面来讲，SQLite和Core Data是很相似的。他们的不同在于具体使用方法。</li>
<li>Core Data代表一个对象的graph model，但SQLite就是一个DBMS。</li>
<li>Apple在一般情况下建议使用Core Data，但是如果你有理由不使用它，那么就去使用更加底层的SQLite吧。</li>
<li>如果你使用SQLite，你可以用FMDB这个库来简化SQLite的操作，这样你就不用花很多经历了解SQLite的C API了。</li>
</ul>

    </div>

    
    
    
        <div class="reward-container">
  <div>希望对您有所帮助，您的支持将是我莫大的动力！</div>
  <button onclick="var qr = document.getElementById('qr'); qr.style.display = (qr.style.display === 'none') ? 'block' : 'none';">
    打赏
  </button>
  <div id="qr" style="display: none;">
      
      <div style="display: inline-block;">
        <img src="/blogwebpage/images/wechatpay.png" alt="Jack Wang 微信支付">
        <p>微信支付</p>
      </div>
      
      <div style="display: inline-block;">
        <img src="/blogwebpage/images/alipay.png" alt="Jack Wang 支付宝">
        <p>支付宝</p>
      </div>

  </div>
</div>


      <footer class="post-footer">
          <div class="post-tags">
              <a href="/blogwebpage/tags/iOS%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" rel="tag"># iOS性能优化</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item"></div>
      <div class="post-nav-item">
    <a href="/blogwebpage/iOS/objective-c/index.html" rel="next" title="Objective-C 语言">
      Objective-C 语言 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%A6%82%E4%BD%95%E6%8F%90%E5%8D%87-tableview-%E7%9A%84%E6%B5%81%E7%95%85%E5%BA%A6%EF%BC%9F"><span class="nav-number">1.</span> <span class="nav-text">如何提升 tableview 的流畅度？</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8D%A1%E9%A1%BF%E4%BC%98%E5%8C%96%E5%9C%A8-CPU-%E5%B1%82%E9%9D%A2"><span class="nav-number">1.1.</span> <span class="nav-text">卡顿优化在 CPU 层面</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8D%A1%E9%A1%BF%E4%BC%98%E5%8C%96%E5%9C%A8-GPU%E5%B1%82%E9%9D%A2"><span class="nav-number">1.2.</span> <span class="nav-text">卡顿优化在 GPU层面</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-%E9%A2%84%E6%8E%92%E7%89%88%EF%BC%8C%E6%8F%90%E5%89%8D%E8%AE%A1%E7%AE%97"><span class="nav-number">1.2.1.</span> <span class="nav-text">1.预排版，提前计算</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-%E9%A2%84%E6%B8%B2%E6%9F%93%EF%BC%8C%E6%8F%90%E5%89%8D%E7%BB%98%E5%88%B6"><span class="nav-number">1.2.2.</span> <span class="nav-text">2.预渲染，提前绘制</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-%E5%BC%82%E6%AD%A5%E7%BB%98%E5%88%B6"><span class="nav-number">1.2.3.</span> <span class="nav-text">3.异步绘制</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-%E5%85%A8%E5%B1%80%E5%B9%B6%E5%8F%91%E7%BA%BF%E7%A8%8B"><span class="nav-number">1.2.4.</span> <span class="nav-text">4.全局并发线程</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-%E9%AB%98%E6%95%88%E7%9A%84%E5%9B%BE%E7%89%87%E5%BC%82%E6%AD%A5%E5%8A%A0%E8%BD%BD"><span class="nav-number">1.2.5.</span> <span class="nav-text">5.高效的图片异步加载</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%A6%82%E4%BD%95%E6%9C%89%E6%95%88%E9%99%8D%E4%BD%8E-APP-%E5%8C%85%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%9F"><span class="nav-number">2.</span> <span class="nav-text">如何有效降低 APP 包的大小？</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%AF%E6%89%A7%E8%A1%8C%E6%96%87%E4%BB%B6"><span class="nav-number">2.1.</span> <span class="nav-text">可执行文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%B5%84%E6%BA%90"><span class="nav-number">2.2.</span> <span class="nav-text">资源</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BB%A7%E7%BB%AD%E4%BC%98%E5%8C%96"><span class="nav-number">3.</span> <span class="nav-text">继续优化</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1%E3%80%81%E9%87%8D%E7%94%A8%E5%92%8C%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BD-lazy-load-Views"><span class="nav-number">3.1.</span> <span class="nav-text">1、重用和延迟加载(lazy load) Views</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2%E3%80%81Cache-Cache-%E8%BF%98%E6%98%AFCache"><span class="nav-number">3.2.</span> <span class="nav-text">2、Cache, Cache, 还是Cache!</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3%E3%80%81%E6%9D%83%E8%A1%A1%E6%B8%B2%E6%9F%93%E6%96%B9%E6%B3%95-%E6%80%A7%E8%83%BD%E8%83%BD%E8%BF%98%E6%98%AF%E8%A6%81bundle%E4%BF%9D%E6%8C%81%E5%90%88%E9%80%82%E7%9A%84%E5%A4%A7%E5%B0%8F%E3%80%82"><span class="nav-number">3.3.</span> <span class="nav-text">3、权衡渲染方法.性能能还是要bundle保持合适的大小。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4%E3%80%81%E5%A4%84%E7%90%86%E5%86%85%E5%AD%98%E8%AD%A6%E5%91%8A-%E7%A7%BB%E9%99%A4%E5%AF%B9%E7%BC%93%E5%AD%98%EF%BC%8C%E5%9B%BE%E7%89%87object%E5%92%8C%E5%85%B6%E4%BB%96%E4%B8%80%E4%BA%9B%E5%8F%AF%E4%BB%A5%E9%87%8D%E5%88%9B%E5%BB%BA%E7%9A%84objects%E7%9A%84strong-references"><span class="nav-number">3.4.</span> <span class="nav-text">4、处理内存警告.移除对缓存，图片object和其他一些可以重创建的objects的strong references.</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5%E3%80%81%E9%87%8D%E7%94%A8%E5%A4%A7%E5%BC%80%E9%94%80%E5%AF%B9%E8%B1%A1"><span class="nav-number">3.5.</span> <span class="nav-text">5、重用大开销对象</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6%E3%80%81%E4%B8%80%E4%BA%9Bobjects%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E5%BE%88%E6%85%A2%EF%BC%8C%E6%AF%94%E5%A6%82NSDateFormatter%E5%92%8CNSCalendar%E3%80%82%E7%84%B6%E8%80%8C%EF%BC%8C%E4%BD%A0%E5%8F%88%E4%B8%8D%E5%8F%AF%E9%81%BF%E5%85%8D%E5%9C%B0%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%E5%AE%83%E4%BB%AC%EF%BC%8C%E6%AF%94%E5%A6%82%E4%BB%8EJSON%E6%88%96%E8%80%85XML%E4%B8%AD%E8%A7%A3%E6%9E%90%E6%95%B0%E6%8D%AE%E3%80%82%E6%83%B3%E8%A6%81%E9%81%BF%E5%85%8D%E4%BD%BF%E7%94%A8%E8%BF%99%E4%B8%AA%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%93%B6%E9%A2%88%E4%BD%A0%E5%B0%B1%E9%9C%80%E8%A6%81%E9%87%8D%E7%94%A8%E4%BB%96%E4%BB%AC%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%E5%88%B0%E4%BD%A0%E7%9A%84class%E9%87%8C%E6%88%96%E8%80%85%E5%88%9B%E5%BB%BA%E9%9D%99%E6%80%81%E5%8F%98%E9%87%8F%E6%9D%A5%E5%AE%9E%E7%8E%B0%E3%80%82"><span class="nav-number">3.6.</span> <span class="nav-text">6、一些objects的初始化很慢，比如NSDateFormatter和NSCalendar。然而，你又不可避免地需要使用它们，比如从JSON或者XML中解析数据。想要避免使用这个对象的瓶颈你就需要重用他们，可以通过添加属性到你的class里或者创建静态变量来实现。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7%E3%80%81%E9%81%BF%E5%85%8D%E5%8F%8D%E5%A4%8D%E5%A4%84%E7%90%86%E6%95%B0%E6%8D%AE-%E5%9C%A8%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E5%92%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E7%9B%B8%E5%90%8C%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BE%88%E9%87%8D%E8%A6%81%E3%80%82"><span class="nav-number">3.7.</span> <span class="nav-text">7、避免反复处理数据.在服务器端和客户端使用相同的数据结构很重要。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#8%E3%80%81%E9%80%89%E6%8B%A9%E6%AD%A3%E7%A1%AE%E7%9A%84%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F-%E8%A7%A3%E6%9E%90JSON%E4%BC%9A%E6%AF%94XML%E6%9B%B4%E5%BF%AB%E4%B8%80%E4%BA%9B%EF%BC%8CJSON%E4%B9%9F%E9%80%9A%E5%B8%B8%E6%9B%B4%E5%B0%8F%E6%9B%B4%E4%BE%BF%E4%BA%8E%E4%BC%A0%E8%BE%93%E3%80%82%E4%BB%8EiOS5%E8%B5%B7%E6%9C%89%E4%BA%86%E5%AE%98%E6%96%B9%E5%86%85%E5%BB%BA%E7%9A%84JSON-deserialization-%E5%B0%B1%E6%9B%B4%E5%8A%A0%E6%96%B9%E4%BE%BF%E4%BD%BF%E7%94%A8%E4%BA%86%E3%80%82%E4%BD%86%E6%98%AFXML%E4%B9%9F%E6%9C%89XML%E7%9A%84%E5%A5%BD%E5%A4%84%EF%BC%8C%E6%AF%94%E5%A6%82%E4%BD%BF%E7%94%A8SAX-%E6%9D%A5%E8%A7%A3%E6%9E%90XML%E5%B0%B1%E5%83%8F%E8%A7%A3%E6%9E%90%E6%9C%AC%E5%9C%B0%E6%96%87%E4%BB%B6%E4%B8%80%E6%A0%B7%EF%BC%8C%E4%BD%A0%E4%B8%8D%E9%9C%80%E5%83%8F%E8%A7%A3%E6%9E%90json%E4%B8%80%E6%A0%B7%E7%AD%89%E5%88%B0%E6%95%B4%E4%B8%AA%E6%96%87%E6%A1%A3%E4%B8%8B%E8%BD%BD%E5%AE%8C%E6%88%90%E6%89%8D%E5%BC%80%E5%A7%8B%E8%A7%A3%E6%9E%90%E3%80%82%E5%BD%93%E4%BD%A0%E5%A4%84%E7%90%86%E5%BE%88%E5%A4%A7%E7%9A%84%E6%95%B0%E6%8D%AE%E7%9A%84%E6%97%B6%E5%80%99%E5%B0%B1%E4%BC%9A%E6%9E%81%E5%A4%A7%E5%9C%B0%E5%87%8F%E4%BD%8E%E5%86%85%E5%AD%98%E6%B6%88%E8%80%97%E5%92%8C%E5%A2%9E%E5%8A%A0%E6%80%A7%E8%83%BD%E3%80%82"><span class="nav-number">3.8.</span> <span class="nav-text">8、选择正确的数据格式.解析JSON会比XML更快一些，JSON也通常更小更便于传输。从iOS5起有了官方内建的JSON deserialization 就更加方便使用了。但是XML也有XML的好处，比如使用SAX 来解析XML就像解析本地文件一样，你不需像解析json一样等到整个文档下载完成才开始解析。当你处理很大的数据的时候就会极大地减低内存消耗和增加性能。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#9%E3%80%81%E6%AD%A3%E7%A1%AE%E8%AE%BE%E5%AE%9A%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87"><span class="nav-number">3.9.</span> <span class="nav-text">9、正确设定背景图片</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#10%E3%80%81%E5%87%8F%E5%B0%91%E4%BD%BF%E7%94%A8Web%E7%89%B9%E6%80%A7%E3%80%82%E6%83%B3%E8%A6%81%E6%9B%B4%E9%AB%98%E7%9A%84%E6%80%A7%E8%83%BD%E4%BD%A0%E5%B0%B1%E8%A6%81%E8%B0%83%E6%95%B4%E4%B8%8B%E4%BD%A0%E7%9A%84HTML%E4%BA%86%E3%80%82%E7%AC%AC%E4%B8%80%E4%BB%B6%E8%A6%81%E5%81%9A%E7%9A%84%E4%BA%8B%E5%B0%B1%E6%98%AF%E5%B0%BD%E5%8F%AF%E8%83%BD%E7%A7%BB%E9%99%A4%E4%B8%8D%E5%BF%85%E8%A6%81%E7%9A%84javascript%EF%BC%8C%E9%81%BF%E5%85%8D%E4%BD%BF%E7%94%A8%E8%BF%87%E5%A4%A7%E7%9A%84%E6%A1%86%E6%9E%B6%E3%80%82%E8%83%BD%E5%8F%AA%E7%94%A8%E5%8E%9F%E7%94%9Fjs%E5%B0%B1%E6%9B%B4%E5%A5%BD%E4%BA%86%E3%80%82%E5%B0%BD%E5%8F%AF%E8%83%BD%E5%BC%82%E6%AD%A5%E5%8A%A0%E8%BD%BD%E4%BE%8B%E5%A6%82%E7%94%A8%E6%88%B7%E8%A1%8C%E4%B8%BA%E7%BB%9F%E8%AE%A1script%E8%BF%99%E7%A7%8D%E4%B8%8D%E5%BD%B1%E5%93%8D%E9%A1%B5%E9%9D%A2%E8%A1%A8%E8%BE%BE%E7%9A%84javascript%E3%80%82%E6%B3%A8%E6%84%8F%E4%BD%A0%E4%BD%BF%E7%94%A8%E7%9A%84%E5%9B%BE%E7%89%87%EF%BC%8C%E4%BF%9D%E8%AF%81%E5%9B%BE%E7%89%87%E7%9A%84%E7%AC%A6%E5%90%88%E4%BD%A0%E4%BD%BF%E7%94%A8%E7%9A%84%E5%A4%A7%E5%B0%8F%E3%80%82"><span class="nav-number">3.10.</span> <span class="nav-text">10、减少使用Web特性。想要更高的性能你就要调整下你的HTML了。第一件要做的事就是尽可能移除不必要的javascript，避免使用过大的框架。能只用原生js就更好了。尽可能异步加载例如用户行为统计script这种不影响页面表达的javascript。注意你使用的图片，保证图片的符合你使用的大小。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#11%E3%80%81Shadow-Path-%E3%80%82CoreAnimation%E4%B8%8D%E5%BE%97%E4%B8%8D%E5%85%88%E5%9C%A8%E5%90%8E%E5%8F%B0%E5%BE%97%E5%87%BA%E4%BD%A0%E7%9A%84%E5%9B%BE%E5%BD%A2%E5%B9%B6%E5%8A%A0%E5%A5%BD%E9%98%B4%E5%BD%B1%E7%84%B6%E5%90%8E%E6%89%8D%E6%B8%B2%E6%9F%93%EF%BC%8C%E8%BF%99%E5%BC%80%E9%94%80%E6%98%AF%E5%BE%88%E5%A4%A7%E7%9A%84%E3%80%82%E4%BD%BF%E7%94%A8shadowPath%E7%9A%84%E8%AF%9D%E5%B0%B1%E9%81%BF%E5%85%8D%E4%BA%86%E8%BF%99%E4%B8%AA%E9%97%AE%E9%A2%98%E3%80%82%E4%BD%BF%E7%94%A8shadow-path%E7%9A%84%E8%AF%9DiOS%E5%B0%B1%E4%B8%8D%E5%BF%85%E6%AF%8F%E6%AC%A1%E9%83%BD%E8%AE%A1%E7%AE%97%E5%A6%82%E4%BD%95%E6%B8%B2%E6%9F%93%EF%BC%8C%E5%AE%83%E4%BD%BF%E7%94%A8%E4%B8%80%E4%B8%AA%E9%A2%84%E5%85%88%E8%AE%A1%E7%AE%97%E5%A5%BD%E7%9A%84%E8%B7%AF%E5%BE%84%E3%80%82%E4%BD%86%E9%97%AE%E9%A2%98%E6%98%AF%E8%87%AA%E5%B7%B1%E8%AE%A1%E7%AE%97path%E7%9A%84%E8%AF%9D%E5%8F%AF%E8%83%BD%E5%9C%A8%E6%9F%90%E4%BA%9BView%E4%B8%AD%E6%AF%94%E8%BE%83%E5%9B%B0%E9%9A%BE%EF%BC%8C%E4%B8%94%E6%AF%8F%E5%BD%93view%E7%9A%84frame%E5%8F%98%E5%8C%96%E7%9A%84%E6%97%B6%E5%80%99%E4%BD%A0%E9%83%BD%E9%9C%80%E8%A6%81%E5%8E%BBupdate-shadow-path"><span class="nav-number">3.11.</span> <span class="nav-text">11、Shadow Path 。CoreAnimation不得不先在后台得出你的图形并加好阴影然后才渲染，这开销是很大的。使用shadowPath的话就避免了这个问题。使用shadow path的话iOS就不必每次都计算如何渲染，它使用一个预先计算好的路径。但问题是自己计算path的话可能在某些View中比较困难，且每当view的frame变化的时候你都需要去update shadow path.</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#12%E3%80%81%E4%BC%98%E5%8C%96Table-View"><span class="nav-number">3.12.</span> <span class="nav-text">12、优化Table View</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#13%E3%80%81%E9%80%89%E6%8B%A9%E6%AD%A3%E7%A1%AE%E7%9A%84%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E9%80%89%E9%A1%B9"><span class="nav-number">3.13.</span> <span class="nav-text">13、选择正确的数据存储选项</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jack Wang"
      src="/blogwebpage/images/avatar.gif">
  <p class="site-author-name" itemprop="name">Jack Wang</p>
  <div class="site-description" itemprop="description">书山有路勤为径，学海无涯苦作舟！</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/blogwebpage/archives/">
        
          <span class="site-state-item-count">52</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/blogwebpage/categories/">
          
        <span class="site-state-item-count">56</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/blogwebpage/tags/">
          
        <span class="site-state-item-count">54</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL0phY2stVmluZw==" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;Jack-Ving"><i class="github fa-fw"></i>GitHub</span>
      </span>
      <span class="links-of-author-item">
        <span class="exturl" data-url="bWFpbHRvOjcyNzg4MTk0NUBxcS5jb20=" title="E-Mail → mailto:727881945@qq.com"><i class="envelope fa-fw"></i>E-Mail</span>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        
  <div class="beian"><span class="exturl" data-url="aHR0cHM6Ly9iZWlhbi5taWl0Lmdvdi5jbg==">京ICP备16036665号-2 </span>
  </div>

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Jack Wang</span>
</div>
  <div class="powered-by">由 <span class="exturl theme-link" data-url="aHR0cHM6Ly9oZXhvLmlv">Hexo</span> & <span class="exturl theme-link" data-url="aHR0cHM6Ly90aGVtZS1uZXh0Lm9yZw==">NexT.Gemini</span> 强力驱动
  </div>

        


  <div style="display: none;">
    <script src="//s95.cnzz.com/z_stat.php?id=1277804316&web_id=1277804316"></script>
  </div>






      </div>
    </footer>
  </div>

  
  <script src="/blogwebpage/lib/anime.min.js"></script>
  <script src="/blogwebpage/lib/velocity/velocity.min.js"></script>
  <script src="/blogwebpage/lib/velocity/velocity.ui.min.js"></script>

<script src="/blogwebpage/js/utils.js"></script>

<script src="/blogwebpage/js/motion.js"></script>


<script src="/blogwebpage/js/schemes/pisces.js"></script>


<script src="/blogwebpage/js/next-boot.js"></script>




  
  <script>
    (function(){
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x=document.getElementsByTagName("link");
		//Find the last canonical URL
		if(x.length > 0){
			for (i=0;i<x.length;i++){
				if(x[i].rel.toLowerCase() == 'canonical' && x[i].href){
					canonicalURL=x[i].href;
				}
			}
		}
    //Get protocol
	    if (!canonicalURL){
	    	curProtocol = window.location.protocol.split(':')[0];
	    }
	    else{
	    	curProtocol = canonicalURL.split(':')[0];
	    }
      //Get current URL if the canonical URL does not exist
	    if (!canonicalURL) canonicalURL = window.location.href;
	    //Assign script content. Replace current URL with the canonical URL
      !function(){var e=/([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,r=canonicalURL,t=document.referrer;if(!e.test(r)){var n=(String(curProtocol).toLowerCase() === 'https')?"https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif":"//api.share.baidu.com/s.gif";t?(n+="?r="+encodeURIComponent(document.referrer),r&&(n+="&l="+r)):r&&(n+="?l="+r);var i=new Image;i.src=n}}(window);})();
  </script>




  
<script src="/blogwebpage/js/local-search.js"></script>













  

  

</body>
</html>
